/*
 *    Copyright (c) 2006 ThoughtWorks, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.thoughtworks.turtlemock.internal;

import junit.framework.Assert;

public class PairRollbackableInvokeLog extends AbstractRollbackableInvokeLog {
    private final RollbackableInvokeLog bottom;
    private final RollbackableInvokeLog top;
    private boolean expectTopTimes;
    private boolean expectBottomTimes;

    public PairRollbackableInvokeLog(RollbackableInvokeLog bottom, RollbackableInvokeLog top) {
        this.bottom = bottom;
        this.top = top;
    }

    public void times(int times) {
        if (times == 0) {
            top.times(0);
            bottom.times(0);
            return;
        }

        String msg = "expected invoke times: " + times + ", actual was: " + timesNotAsserted();
        Assert.assertTrue(msg, times <= timesNotAsserted());

        int remain = times - top.timesNotAsserted();
        expectTopTimes = top.timesNotAsserted() > 0;
        expectBottomTimes = remain > 0;
        if (expectTopTimes) {
            top.times(expectBottomTimes ? top.timesNotAsserted() : times);
        }
        if (expectBottomTimes) {
            bottom.times(remain);
        }
    }

    public int timesNotAsserted() {
        return bottom.timesNotAsserted() + top.timesNotAsserted();
    }

    public void rollback() {
        if (expectTopTimes) {
            top.rollback();
        }
        if (expectBottomTimes) {
            bottom.rollback();
        }
    }
}
